// ApexWindow.cpp
// by Charles Mc Auley
// "Programming AutoCAD 2000 with ObjectARX"


#include <acdb.h>		// acdb definitions
#include <adslib.h>		// ads defs
#include <dbsymtb.h>
#include <dbents.h>
#include <gepnt2d.h>
#include <gept2dar.h>
#include <math.h>
#include <gelnsg2d.h>


#include "RectWindow.h"
#include "ApexWindow.h"

ApexWindow::ApexWindow()
{
}

ApexWindow::~ApexWindow()
{
}

void ApexWindow::drawWindow(AcDbBlockTableRecord* pBlkTableRecord)
{

	// Call the base class to draw the
	// rectangular part of the window
	RectWindow::drawWindow(pBlkTableRecord);
	if(!drawApex(pBlkTableRecord))
	{
		acutPrintf("\nError drawing Apex. ");
		return;
	}
}

Adesk::Boolean ApexWindow::drawApex(AcDbBlockTableRecord* pBlkTableRecord)
{
	AcGePoint2d sp, tp, ep, llPt;
	AcGePoint2d ll, lr, ur, ul;
	AcGePoint2d leftMid, rightMid, btmMid, intPt, vertTp;
	AcGePoint2dArray apexAr;
	AcGePoint2dArray intBarAr;
	AcGeLineSeg2d leftApexSide, rightApexSide;
	AcGeLineSeg2d btmApexSide, horMidLine;
	AcGeLine2d perpLine;
	AcGeVector2d vec;
	AcGeTol tol;

	double windLen, windHt, frameThk, intrFrameThk;
	double deg45cut;

	windLen			= getWindowLength();
	windHt			= getWindowHeight();
	llPt			= getWindowStartPoint();
	frameThk		= getRectFrameThk();
	intrFrameThk	= getIntrFrameThk();

	// Calculate the start point, top point
	// and end point of the arc.
	vec.set(0, windHt);
	sp = llPt + vec;

	vec.set(windLen, 0);
	ep = sp + vec;

	vec.set((windLen / 2), (windLen / 2));
	tp = sp + vec;

	apexAr.append(sp);
	apexAr.append(tp);
	apexAr.append(ep);

	// now reset sp, tp, ep
	// by the hypotenuse of the frame thickness
	// cut at 45 degrees. sqrt and pow are part
	// of the math.h header file.
	deg45cut = sqrt( pow(frameThk, 2.0) + pow(frameThk, 2.0));

	vec.set(deg45cut, 0);
	sp += vec;
	ep -= vec;
	vec.set(0, deg45cut);
	tp -= vec;

	apexAr.append(ep);
	apexAr.append(tp);
	apexAr.append(sp);

	vertTp = tp;

	// Initialize the line segments
	leftApexSide.set(sp, tp);
	rightApexSide.set(tp, ep);
	btmApexSide.set(sp, ep);

	// Get the midpoints of leftApexSide and rightApexSide
	leftMid = leftApexSide.midPoint();
	rightMid = rightApexSide.midPoint();

	// Initialize the horizontal line horMidLine
	horMidLine.set(leftMid, rightMid);

	// Get the midpoint of the horMidLine
	intPt = horMidLine.midPoint();

	// Call the base class
	// RectWindow::drawIntBar() to 
	// draw the polyline even though
	// this is not an internal bar it
	// does accept an AcDbBlockTableRecord pointer
	// and an AcGePoint2dArray so it will suit our
	// purpose.

	if(!drawIntBar(pBlkTableRecord, apexAr))
	{
		acutPrintf("\nError drawing Apex. ");
		return Adesk::kFalse;
	}

	// Draw the horizontal internal bars first
	sp = leftMid;
	ep = intPt;
	vec.set((intrFrameThk / 2), (intrFrameThk / 2));
	ul = sp + vec;
	ll = sp - vec;
	lr = ep - vec;
	vec.set( -(intrFrameThk / 2), (intrFrameThk / 2));
	ur = ep + vec;

	intBarAr.append(ll);
	intBarAr.append(lr);
	intBarAr.append(ep);
	intBarAr.append(ur);
	intBarAr.append(ul);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	// Dont forget to empty out the array
	intBarAr.setLogicalLength(0);

	sp = intPt;
	ep = rightMid;
	vec.set((intrFrameThk / 2), -(intrFrameThk / 2));
	ll = sp + vec;
	lr = ep + vec;
	ur = ep - vec;
	vec.set((intrFrameThk / 2), (intrFrameThk / 2));
	ul = sp + vec;

	intBarAr.append(ll);
	intBarAr.append(lr);
	intBarAr.append(ur);
	intBarAr.append(ul);
	intBarAr.append(sp);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	intBarAr.setLogicalLength(0);

	// Draw the vertical internal bars

	sp = intPt;
	ep = vertTp;
	vec.set((intrFrameThk / 2), (intrFrameThk / 2));
	lr = sp + vec;
	ul = ep - vec;
	vec.set( -(intrFrameThk / 2), (intrFrameThk / 2));
	ll = sp + vec;
	ur = ep - vec;

	intBarAr.append(sp);
	intBarAr.append(lr);
	intBarAr.append(ur);
	intBarAr.append(ep);
	intBarAr.append(ul);
	intBarAr.append(ll);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	intBarAr.setLogicalLength(0);

	// Initialize the btmMid point
	btmMid = btmApexSide.midPoint();

	sp = btmMid;
	ep = intPt;
	vec.set((intrFrameThk / 2), 0);
	lr = sp + vec;
	ll = sp - vec;
	vec.set( -(intrFrameThk / 2), -(intrFrameThk / 2));
	ul = ep + vec;
	vec.set((intrFrameThk / 2), -(intrFrameThk / 2));
	ur = ep + vec;

	intBarAr.append(lr);
	intBarAr.append(ur);
	intBarAr.append(ep);
	intBarAr.append(ul);
	intBarAr.append(ll);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	intBarAr.setLogicalLength(0);

	// Draw the left Vertical bar
	btmApexSide.getPerpLine(leftMid, perpLine);
	btmApexSide.intersectWith(perpLine, lr, tol);

	vec.set(0, -(intrFrameThk / 2));
	ur = leftMid + vec;
	vec.set( -(intrFrameThk / 2), 0);
	ep = ur + vec;
	vec.set( -(intrFrameThk / 2), -(intrFrameThk / 2));
	ul = ep + vec;
	vec.set( -(intrFrameThk), 0);
	ll = lr + vec;

	intBarAr.append(lr);
	intBarAr.append(ur);
	intBarAr.append(ep);
	intBarAr.append(ul);
	intBarAr.append(ll);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	intBarAr.setLogicalLength(0);


	// Draw the right Vertical bar
	btmApexSide.getPerpLine(rightMid, perpLine);
	btmApexSide.intersectWith(perpLine, ll, tol);

	vec.set(0, -(intrFrameThk / 2));
	ul = rightMid + vec;
	vec.set((intrFrameThk / 2), 0);
	ep = ul + vec;
	vec.set((intrFrameThk / 2), -(intrFrameThk / 2));
	ur = ep + vec;
	vec.set((intrFrameThk), 0);
	lr = ll + vec;

	intBarAr.append(lr);
	intBarAr.append(ur);
	intBarAr.append(ep);
	intBarAr.append(ul);
	intBarAr.append(ll);

	if(!drawIntBar(pBlkTableRecord, intBarAr))
	{
		acutPrintf("\nError drawing internal apex bar. ");
		return Adesk::kFalse;
	}

	intBarAr.setLogicalLength(0);

	return Adesk::kTrue;
}


Adesk::Boolean ApexWindow::drawApexInternalBars(AcDbBlockTableRecord *pBlkTableRecord)
{
	return Adesk::kTrue;
}

void ApexWindow::setWindowHeight(double windHeight)
{
	double windLen = getWindowLength();
	rectFrameHt = windHeight - (windLen / 2);
	RectWindow::setWindowHeight(rectFrameHt);
}